// 1 导入react
import React from 'react'
import ReactDOM from 'react-dom'

// 引入css文件
import "./index.css"

// 组件性能优化
// 减轻 state: 只存储跟组件渲染相关的数据(比如 count/list/loading 等数据)
// 注意: 不用做渲染的数据不要放在state中 比如 定时器ID等
// 对于这种需要在多个方法中用的数据 应该放在this中


// 避免不必要的重写渲染

// 组件更新机制: 父组件根系会引起子组件也被更新 这种思路很清晰
// 问题: 子组件没有任何变化时也会重新渲染
// 如何避免不必要的重写渲染??
// 解决方法 使用钩子函数 shouldComponentUpdate(nextProps,nextState)
// 作用: 通过返回值决定该组件是否重新渲染,返回值 true 表示重新渲染 false表示不渲染  也只是是否执行render方法
// 触发时机: 更新阶段的钩子函数, 组件重新渲染前执行 (shouldComponentUpdate=>render)



// 纯组件
// 说明: 纯组件内部的对比是shallow compare (浅层对比)
// 对于值类型来说: 对比两个值是否相同(直接赋值即可 没有坑)


const obj = { number: 0 }
const newObj = obj
newObj.number = 23
console.log(newObj.number === obj.number)

// 使用纯组件
class App extends React.Component {


    state = {
        count: 0,
        obj: { number: 0 }
    }

    // 错误演示

    handlerClick = (e) => {
        const newObj = this.state.obj
        newObj.number = Math.floor(Math.random() * 3)
        this.setState((state, props) => {
            return {
                count: state.count + 1,
                obj: newObj
            }
        })
    }

    // handlerClick = (e) => {
    //     const newObj = { ...this.state.obj, number: Math .floor(Math.random() * 3) }
    //     // const list = [...this.state.list, {Math.floor(Math.random() * 3) }]
    //     this.setState((state, props) => {
    //         return {
    //             count: state.count + 1,
    //             obj: newObj
    //         }
    //     })
    // }

    // 钩子函数
    // 因为两次生成的随机数可能相同 如果相同不需要重新渲染
    // shouldComponentUpdate(nextProps, nextState) {
    //     console.log('最新的state', nextProps)
    //     console.log('this.props', this.props)
    //     // return false 阻止页面渲染
    //     console.log(this.state.number)
    //     console.log(nextState.number)
    //     return nextState.number !== this.state.number
    // }




    render() {
        // console.log("reder")
        return (
            <div>
                <NumberBox obj={this.state.obj} />
                <button onClick={this.handlerClick}>重新生成</button>
            </div>
        )
    }
}


class NumberBox extends React.Component {



    state = {
        obj: { number: 0 }
    }
    shouldComponentUpdate(nextProps, nextState) {
        console.log('最新的state', nextProps)
        console.log('this.props', this.state)
        // return false 阻止页面渲染
        console.log(this.state.obj.number)
        console.log(nextProps.obj.number)
        return nextProps.obj !== this.state.obj
    }
    render() {
        console.log("reder")
        return <h1>随机数: {this.props.obj.number}</h1>
    }

    componentDidMont() {
        this.setState((preState, props) => {
            return {
                obj: props.obj
            }
        })
    }
}

//3 渲染react元素
ReactDOM.render(
    <App />,
    document.getElementById('root'))
